// This is an open source non-commercial project. Dear PVS-Studio, please check it.
// PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com

// ReSharper disable CheckNamespace
// ReSharper disable ClassNeverInstantiated.Global
// ReSharper disable CommentTypo
// ReSharper disable IdentifierTypo
// ReSharper disable InconsistentNaming
// ReSharper disable StringLiteralTypo
// ReSharper disable UnusedParameter.Local

/*
 * Ars Magna project, http://arsmagna.ru
 */

#region Using directives

using System;
using System.Collections.Generic;
using System.Text;
using System.Data;
using System.ComponentModel;

using AM.Reporting.Utils;

#endregion

#nullable enable

namespace AM.Reporting.Data
{
    /// <summary>
    /// Represents a master-detail relation between two data sources.
    /// </summary>
    /// <remarks>
    /// To setup a relation, you must specify parent and child datasources. For a parent datasource,
    /// you must specify set of key columns; for child datasource, you must specify set of columns that
    /// relate to the parent key columns.
    /// <example>This example shows how to create relation between Customers and Orders tables:
    /// <code>
    /// Report report1;
    /// DataSourceBase customersTable = report1.Dictionary.DataSources.FindByAlias("Customers");
    /// DataSourceBase ordersTable = report1.Dictionary.DataSources.FindByAlias("Orders");
    /// Relation rel = new Relation();
    /// rel.Name = "customersOrders";
    /// rel.ParentDataSource = customersTable;
    /// rel.ChildDataSource = ordersTable;
    /// rel.ParentColumns = new string[] { "CustomerID" };
    /// rel.ChildColumns = new string[] { "CustomerID" };
    /// report1.Dictionary.Relations.Add(rel);
    /// </code>
    /// </example>
    /// </remarks>
    [TypeConverter (typeof (TypeConverters.RelationConverter))]
    public partial class Relation : DataComponentBase
    {
        #region Fields

        #endregion

        #region Properties

        /// <summary>
        /// Gets or sets the parent datasource.
        /// </summary>
        [Category ("Data")]
        public DataSourceBase ParentDataSource { get; set; }

        /// <summary>
        /// Gets or sets the child datasource.
        /// </summary>
        [Category ("Data")]
        public DataSourceBase ChildDataSource { get; set; }

        /// <summary>
        /// Gets or sets an array of parent datasource columns.
        /// </summary>
        /// <remarks>
        /// Note: both <see cref="ParentColumns"/> and <see cref="ChildColumns"/> must have the
        /// same number of elements.
        /// </remarks>
        [Category ("Data")]
        public string[] ParentColumns { get; set; }

        /// <summary>
        /// Gets or sets an array of child datasource columns.
        /// </summary>
        /// <remarks>
        /// Note: both <see cref="ParentColumns"/> and <see cref="ChildColumns"/> must have the
        /// same number of elements.
        /// </remarks>
        [Category ("Data")]
        public string[] ChildColumns { get; set; }

        #endregion

        #region Public Methods

        /// <inheritdoc/>
        public override void Serialize (ReportWriter writer)
        {
            base.Serialize (writer);
            writer.WriteRef ("ParentDataSource", ParentDataSource);
            writer.WriteRef ("ChildDataSource", ChildDataSource);
            writer.WriteValue ("ParentColumns", ParentColumns);
            writer.WriteValue ("ChildColumns", ChildColumns);
            writer.WriteBool ("Enabled", Enabled);
        }

        /// <summary>
        /// Compares this relation with another one.
        /// </summary>
        /// <param name="rel">Another relation to compare with.</param>
        /// <returns><b>true</b> if both relations are equal; <b>false</b> otherwise.</returns>
        public bool Equals (Relation rel)
        {
            return ParentDataSource == rel.ParentDataSource &&
                   ChildDataSource == rel.ChildDataSource &&
                   Converter.ToString (ParentColumns) == Converter.ToString (rel.ParentColumns) &&
                   Converter.ToString (ChildColumns) == Converter.ToString (rel.ChildColumns);
        }

        #endregion

        /// <summary>
        /// Initializes a new instance of the <see cref="Relation"/> class with default settings.
        /// </summary>
        public Relation()
        {
            SetFlags (Flags.CanEdit, true);
        }
    }
}
